-- log_mgr.lua

require("core.Store")

local sformat    = string.format
local ldir       = stdfs.dir
local lfilename  = stdfs.filename
local lmkdir     = stdfs.mkdir
local tinsert    = table.insert
local tsort      = table.sort

LogMgr     = singleton()
local prop = property(LogMgr)
prop:accessor("cache_path", "")
prop:accessor("user_log_cache_path", "")
prop:accessor("local_files", {})
prop:accessor("log_tree", {})

function LogMgr:__init()
    self.cache_path = os.getenv("USERPROFILE") .. "/AppData/LocalLow/Pathea Games/StoreEditor/cache"
end

function LogMgr:loadLocalLogs()
    local dirs = ldir(g_world_mgr.user_log_cache_path)
    for _, dir in pairs(dirs or {}) do
        if dir.type == "directory" then
            local name = lfilename(dir.name)
            print("name:"..name)
        end
    end
end

-- 辅助函数：去除"./logs/"前缀
function LogMgr:removePrefix(path)
    return path:gsub("^%.%/logs%/", "")
end


-- 拆分路径为目录和文件名
function LogMgr:splitPath(path)
    -- 找到最后一个反斜杠的位置
    local last_separator = path:match("^.*()\\")
    if last_separator then
        local dir = path:sub(1, last_separator - 1)
        local filename = path:sub(last_separator + 1)
        return dir, filename
    else
        -- 如果没有反斜杠，整个路径就是文件名
        return "", path
    end
end

-- 提取文件名中的日期
function LogMgr:extractDatetime(filename)
    local date_part, time_part = filename:match("(%d%d%d%d%d%d%d%d)%-(%d%d%d%d%d%d)%.?")
    if date_part and time_part then
        local year = date_part:sub(1, 4)
        local month = date_part:sub(5, 6)
        local day = date_part:sub(7, 8)
        local hour = time_part:sub(1, 2)
        local minute = time_part:sub(3, 4)
        local second = time_part:sub(5, 6)
        local timestamp = os.time({
            year = tonumber(year),
            month = tonumber(month),
            day = tonumber(day),
            hour = tonumber(hour),
            min = tonumber(minute),
            sec = tonumber(second)
        })
        return string.format("%s-%s-%s %s:%s:%s", year, month, day, hour, minute, second), timestamp
    else
        return "", 0
    end
end

function LogMgr:newNode(name, is_file, dirs, server_path, client_path)
    local datetime, timestamp = self:extractDatetime(name)
    return {
        name = name,
        is_file = is_file,
        children_map = {},
        children = {},
        dirs = dirs,
        datetime = datetime,
        timestamp = timestamp,
        server_path = server_path,
        client_path = client_path
    }
end

function LogMgr:buildTree(files)
    local root = self:newNode("logs", false)
    for _, path in ipairs(files) do
        -- 去除./logs的剩余路径
        local rel_path = self:removePrefix(path)
        -- 路径(例如/sidecar-1/error),文件名(带后缀)
        local dirs, filename = self:splitPath(rel_path)
        -- 客户端路径
        local client_path = sformat("%s/%s", g_world_mgr.user_log_cache_path, rel_path)
        -- 处理目录路径
        local current = root
        for dir in dirs:gmatch("([^\\]+)") do
            if not current.children_map[dir] then
                current.children_map[dir] = self:newNode(dir, false, dirs, path, client_path)
            end
            current = current.children_map[dir]
        end
        -- 添加文件节点
        if filename ~= "" then
            current.children_map[filename] = self:newNode(filename, true, dirs, path, client_path)
        end
    end
    return root
end

function LogMgr:treeSort(node)
    if node.is_file then
        return
    end
    node.children = {}
    for _,child in pairs(node.children_map) do
        tinsert(node.children, child)
        self:treeSort(child)
    end
    tsort(node.children, function(a, b)
        -- 目录排前面
        if a.is_file ~= b.is_file then
            return b.is_file
        end
        -- 都是文件的情况
        if a.is_file then
            -- 有日期的优先
            if a.timestamp and b.timestamp then
                return a.timestamp > b.timestamp  -- 日期降序
            elseif a.timestamp then
                return true
            elseif b.timestamp then
                return false
            end
            -- 都没有日期按名称排序
            return a.name < b.name
        end
        -- 都是名称,按文件名排序
        return a.name < b.name
    end)
end

function LogMgr:loadRemoteLogs(callback)
    g_lan_mgr:send_no_anim("logfile_list", {}, function(err, data)
        if err then
            print("[LogMgr][loadRemoteLogs] logfile_list err:" .. err)
            callback(err)
            return
        end
        self.log_tree = {}
        local files = data.files
        self.log_tree = self:buildTree(files)
        self:treeSort(self.log_tree)
        callback()
    end, nil, false)
end

function LogMgr:load(callback)
    self:loadLocalLogs()
    self:loadRemoteLogs(callback)
end

function LogMgr:downLogFile(dirs, server_path, client_path, callback)
    print("[LogMgr][downLogFile] server_path:"..server_path.." client_path:"..client_path)
    g_event_mgr:notifyListener("onProgress", 1, 0)
    g_lan_mgr:down_file("logfile_download", {file_path=server_path}, function(err, data)
        if err then
            print("[LogMgr][storage_download] err="..err)
            callback(err)
            return
        end
        print("[LogMgr][downLogFile] success!")
        local log_path = sformat("%s/%s", g_world_mgr.user_log_cache_path, dirs)
        lmkdir(log_path)
        local contents = data.contents
        g_lan_mgr:write_file(client_path, contents)
        callback(nil)
    end,
    function(max, val)
        g_event_mgr:notifyListener("onProgress", max, val)
    end)
end
g_log_mgr = LogMgr()
